#pragma once
#include "logMessage.hpp"
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <unistd.h>
namespace Server
{
    enum
    {
        USAGE_ERR = 1,
        SOCKET_ERR,
        BIND_ERR,
        LISTEN_ERR
    };

    using namespace std;

    static const uint16_t gport = 8080;
    static const uint16_t gbacklog = 5;
    class tcpServer
    {
    public:
        tcpServer(const uint16_t &port = gport)
            : listen_sockfd_(-1), port_(port)
        {
        }

        void InitServer()
        {
            // 1.创建socket
            listen_sockfd_ = socket(AF_INET, SOCK_STREAM, 0);
            if (listen_sockfd_ < 0)
            {
                logMessage(FATAL, "create socket error");
                exit(SOCKET_ERR);
            }
            logMessage(NORMAL, "create socket success");

            // 2.bind网络信息
            struct sockaddr_in local;
            memset(&local,0,sizeof(local));
            local.sin_family=AF_INET;
            local.sin_port=htons(port_);
            local.sin_addr.s_addr=INADDR_ANY;
            if(bind(listen_sockfd_,(struct sockaddr*)&local,sizeof(local))<0)
            {
                logMessage(FATAL,"bind socket error");
                exit(BIND_ERR);
            }

            logMessage(NORMAL,"bind socket success");
            
            //3.设置socket为监听状态
            if(listen(listen_sockfd_,gbacklog)<0)
            {
                logMessage(FATAL,"listen socket error");
                exit(LISTEN_ERR);
            }
            logMessage(NORMAL,"listen socket success");

        }
        void start()
        {
            for(; ;)
            {
                //4.server获取新链接
                struct sockaddr_in peer;
                socklen_t len=sizeof(peer);
                //sock:和客户端通信的文件描述符
                int sock=accept(listen_sockfd_,(struct sockaddr*)&peer,&len);
                if(sock<0)//没有获取新链接成功就执行下一次循环
                {
                    logMessage(FATAL,"accpect sock error");
                    continue;
                }
                logMessage(NORMAL,"accept sock success");
                std::cout<<"sock"<<sock<<endl;

                //5.通信就用sock文件描述符，面向字节流，后续都是文件操作
                /*version1*/
                serverIO(sock);
                close(sock);
            }
        }
        void serverIO(int sock)
        {
            char buffer[1024];
            while (true)
            {
                ssize_t n=read(sock,buffer,sizeof(buffer)-1);
                if(n>0)
                {
                    buffer[n]=0;
                    std::cout<<"recv message "<<buffer<<endl;
                    string outbuffer=buffer;
                    outbuffer+="server[echo]";
                    write(sock,outbuffer.c_str(),outbuffer.size());
                }
                else if(n==0)
                {
                    //客户端退出
                    logMessage(NORMAL,"client quit ,me too!!");
                    break;
                }
            }
            
        }
        ~tcpServer()
        {
        }

    private:
        int listen_sockfd_;//不负责通信，只负责监听链接，获取新链接
        uint16_t port_;
    };
}